<template>
    <div class="tiled-calendar">
        <el-empty
            v-show="calendar.length == 0"
            description="暂无数据"
            :image-size="60"
        />
        <div class="calendar-header" v-if="calendar.length > 0">
            <span :class="getWeekClass(year)">{{ monthCN[month] }}月</span>
        </div>
        <ul class="calendar-week" v-if="calendar.length > 0">
            <li
                v-for="(item, index) in calendarWeek"
                :key="index"
                class="calendar-week-item"
                :class="item == '六' || item == '日' ? 'weekendColor' : ''"
            >
                {{ item }}
            </li>
        </ul>
        <ul class="calendar-body">
            <li
                v-for="(item, index) in calendar"
                :key="index"
                class="calendar-day"
                @click="onDay(item)"
            >
                <div
                    class="calendar-day-item"
                    :class="getCellClass(item, index)"
                >
                    <div class="adjustWork" v-if="item.dayCodeInfo == '调休日'">
                        班
                    </div>
                    <div
                        class="adjustWork holidayWork"
                        v-if="item.dayCodeInfo == '节假日'"
                    >
                        休
                    </div>
                    <div
                        class="adjustWork todayWork"
                        v-if="item.workDate == today"
                    >
                        今
                    </div>
                    <p style="font-size: 14px; font-weight: 600">
                        {{ item.day }}
                    </p>
                    <p v-if="item.dayCodeInfo == '节假日'">
                        {{ holidayNameFn(item.holidayName, item) }}
                    </p>
                    <p v-else>
                        {{
                            item.lunarday == "初一"
                                ? item.lunarmonth
                                : item.lunarday
                        }}
                    </p>
                </div>
            </li>
        </ul>
    </div>
</template>
  
  <script>
import dayjs from "dayjs";
import { getLunar } from "chinese-lunar-calendar";
import schedulingHttp from "@/https/scheduling.js";
import moment from "moment";

const monthCN = [
    "一",
    "二",
    "三",
    "四",
    "五",
    "六",
    "七",
    "八",
    "九",
    "十",
    "十一",
    "十二",
];

export default {
    props: {
        year: {
            type: [String, Number],
            default: 2023,
        },
        month: {
            type: [String, Number],
            default: 0,
        },
        // 是否在当月日历中展示上个月和下个月的部分日期，默认不展示。
        hasCurrentMonth: {
            type: Boolean,
            default: false,
        },
        // 休息日
        weekendList: Array,
        // 工作日
        workList: {
            type: Array,
            default: () => [],
        },
        // 既非工作日也非休息日
        workRestOffList: Array,
    },
    data() {
        return {
            calendarWeek: ["一", "二", "三", "四", "五", "六", "日"],
            today: moment().format("YYYY-MM-DD"),
            isCtrl: false,
            isShift: false,
            monthCN,
            selectedList: [],
            calendar: [],
        };
    },
    watch: {
        year(newV, oldV) {
            this.getHoliday();
        },
    },
    computed: {},
    mounted() {
        this.onKeyEvent();
        this.getHoliday();
    },
    methods: {
        onKeyEvent() {
            window.addEventListener("keydown", (e) => {
                const _e = e || window.event;
                switch (_e.keyCode) {
                    case 16:
                        this.isShift = true;
                        break;
                    case 17:
                        this.isCtrl = true;
                        break;
                }
            });

            window.addEventListener("keyup", (e) => {
                const _e = e || window.event;
                switch (_e.keyCode) {
                    case 16:
                        this.isShift = false;
                        break;
                    case 17:
                        this.isCtrl = false;
                        break;
                }
            });
        },
        // 是否是当前月
        isCurrentMonth(date) {
            const { year: currentYear, month: currentMonth } = this.getNewDate(
                this.getDate(this.year, this.month, 1)
            );
            const { year, month } = this.getNewDate(date);
            return currentYear === year && currentMonth === month;
        },
        onDay(item) {
            // 如果是同一年，当点击的月份小于当前系统日期的月份，则禁止点击。
            if (
                item.year === new Date().getFullYear() &&
                item.month < new Date().getMonth() + 1
            ) {
                return;
            }

            // 如果是同一年又是同一个月，当点击的日期小于当前的日期，则禁止点击
            if (
                item.year === new Date().getFullYear() &&
                item.month === new Date().getMonth() + 1 &&
                item.day < new Date().getDate()
            ) {
                return;
            }

            // 如果点击的年份小月当前年份，则禁止点击。
            if (item.year < new Date().getFullYear()) {
                return;
            }

            // 如果点击的日期不是那个月应有的日期（每个月的日期里边也会包含上个月和下个月的某几天日期，只是这些日期的颜色被置灰了），则禁止点击。
            if (!this.isCurrentMonth(item.date)) {
                return;
            }

            const dateStr = dayjs(item.date).format("YYYYMMDD");
            const { isCtrl, isShift } = this;

            // 按住ctrl
            if (isCtrl && !isShift) {
                this.setSelectCalendar({ dateStr, item, isCtrl });
            } else if (isCtrl && isShift) {
                // 同时按住ctrl和shift
                this.setSelectCalendar({ dateStr, item, isCtrl, isShift });
            } else if (isShift && !isCtrl) {
                // 按住shift
                this.setSelectCalendar({ dateStr, item, isShift });
            } else {
                // 不按ctrl和shift，一次只能选择一个
                this.setSelectCalendar({ dateStr, item });
            }
        },
        getWeekClass(year, month) {
            if (year < new Date().getFullYear()) return "is-disabled";

            if (
                year === new Date().getFullYear() &&
                month < new Date().getMonth() + 1
            )
                return "is-disabled";
        },
        getCellClass(item, idx) {
            if (item.dayCodeInfo == "节假日") {
                return "holidayColor";
            } else if (item.dayCodeInfo == "双休日") {
                return "weekdayColor";
            } else if (item.workDate == this.today) {
                return "todayColor";
            } else {
                return "";
            }
        },

        lunarDate(pDate, item) {
            const date = new Date(item.date);
            const curYear = date.getFullYear(); // 当前年份
            const curMonth = date.getMonth() + 1; // 当前月份
            const curDay = date.getDate(); // 当前日期
            const lunarDate = getLunar(curYear, curMonth, curDay);
            if (lunarDate.dateStr.indexOf("初一") > -1) {
                return lunarDate.dateStr.slice(0, 2);
            } else {
                return lunarDate.dateStr.slice(2, 4);
            }
        },
        async getHoliday() {
            const res = await schedulingHttp.workcalendarGetWorkCalendar({
                year: this.year,
                month: this.month + 1,
            });
            res.data.data.forEach((item) => {
                item.day = moment(item.workDate).format("DD");
                item.date = new Date(item.workDate);
                item.isCurrentMonth = true;
            });
            this.holidayList = res.data.data;

            let calendatArr = [];
            let weekDay = 0;
            let weekDayIndex = moment(res.data.data[0].workDate).weekday();
            // 获取当前月第一天星期几
            if (weekDayIndex == 0) {
                weekDay = 6;
            } else {
                weekDay = weekDayIndex - 1;
            }
            // 为了页面整齐排列 一并绘制42天
            for (let i = 0; i < 42; i++) {
                if (
                    i >= weekDay &&
                    i <= weekDay + this.holidayList.length - 1
                ) {
                    calendatArr.push(this.holidayList[i - weekDay]);
                } else {
                    calendatArr.push({
                        isCurrentMonth: false,
                    });
                }
            }
            this.calendar = calendatArr;
        },
        getHolidayInfo(date) {
            let currentDateInfo = {};
            this.holidayList.forEach((item) => {
                if (date == item.workDate) {
                    currentDateInfo = item;
                }
            });
            return currentDateInfo;
        },

        getNewDate(date) {
            console.log(date);
            const year = date.getFullYear();
            const month = date.getMonth();
            const day = date.getDate();
            return { year, month, day };
        },
        getDate(year, month, day) {
            return new Date(year, month, day);
        },
        holidayNameFn(name, item) {
            let holidayName = "";
            if (name == "元旦节" && item.day == "01") {
                console.log(name, item);
                holidayName = "元旦";
            } else if (name == "春节" && item.lunarday == "初一") {
                holidayName = name;
            } else if (name == "清明节" && item.day == "05") {
                holidayName = "清明";
            } else if (name == "劳动节" && item.day == "01") {
                holidayName = "劳动";
            } else if (name == "端午节" && item.lunarday == "初五") {
                holidayName = "端午";
            } else if (name == "中秋节" && item.lunarday == "十五") {
                holidayName = "中秋";
            } else if (name == "国庆节" && item.day == "01") {
                holidayName = "国庆";
            } else {
                holidayName = item.lunarday;
            }
            return holidayName;
        },
    },
    beforeDestroy() {
        window.removeEventListener("keydown");
        window.removeEventListener("keyup");
    },
};
</script>
  
  <style lang="less" scoped>
.calendar-header,
.calendar-week {
    user-select: none;
    .is-disabled {
        cursor: not-allowed;
        opacity: 0.5;
    }
}
.tiled-calendar {
    height: 100%;
    box-sizing: border-box;
    margin: 0 20px 10px;
    font-size: 14px;
    ul,
    li {
        margin: 0;
        padding: 0;
    }
    .calendar-header {
        border-bottom: 1px solid #edeef1;
        padding: 12px 0;
        color: #1b1f26;
        text-align: center;
        margin-bottom: 8px;
    }
    .calendar-week {
        display: flex;
        height: 28px;
        line-height: 28px;
        border-right: none;
        border-left: none;
        margin-bottom: 2px;
        .calendar-week-item {
            list-style-type: none;
            width: 14.28%;
            text-align: center;
            color: #737985;

            &.weekendColor {
                color: #eb3333;
            }
        }
    }
    .calendar-body {
        display: flex;
        flex-wrap: wrap;
        margin-top: 5px;
        .calendar-day {
            width: 14.28%;
            text-align: center;
            height: 44px;
            line-height: 44px;
            position: relative;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            .calendar-day-item {
                display: block;
                border-radius: 4px;
                padding: 4px 6px;
                cursor: pointer;
                user-select: none;
                color: #666;
                position: relative;
                p {
                    width: 100%;
                    line-height: 1 !important;
                    font-size: 12px;
                    margin: 2px 0;
                }
                &.holidayColor {
                    color: #eb3333;
                    background: rgba(235, 51, 51, 0.05);
                }
                &.weekdayColor {
                    color: rgba(230, 0, 18, 0.4);
                }
                &.todayColor {
                    background: #4e6ef2;
                    color: #fff;
                }
                .adjustWork {
                    background: #4e5877;
                    color: #fff;
                    position: absolute;
                    right: -4px;
                    top: -4px;
                    border-radius: 3px;
                    width: 14px;
                    height: 14px;
                    font-size: 10px;
                    line-height: 14px;
                }
                .holidayWork {
                    background: #eb3333;
                }
                .todayWork {
                    background: #6b88ff;
                }
                &:hover {
                    background: rgba(69, 115, 243, 0.12);
                }
            }
            .is {
                &-today,
                &-selected {
                    border: 1px solid #e60012;
                    &:hover {
                        background: rgba(69, 115, 243, 0.12);
                    }
                }
                &-selected {
                    border: 1px solid #4573f3;
                    &:hover {
                        background: none;
                    }
                }
                &-disabled {
                    cursor: not-allowed;
                    color: #9e9e9e;
                    &:hover {
                        background: none;
                    }
                }
                &-weekend {
                    color: #e60012;
                }
                &-workRestOff {
                    color: #ff7d00;
                }
                &-disabled {
                    &.is-workRestOff {
                        color: rgba(255, 125, 0, 0.4);
                    }
                }
                &-disabled {
                    &.is-weekend {
                        color: rgba(230, 0, 18, 0.4);
                    }
                }
                &-work {
                    color: #1b1f26;
                }
                &-disabled.is-work {
                    color: #9e9e9e;
                }
            }
        }
    }
}
</style>
  